package com.zl.learning.reflect;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class MethodDemo {
    public static class MethodDemo1 {
        public static void main(String[] args) {
            //要获取print(int ,int )方法  1.要获取一个方法就是获取类的信息，获取类的信息首先要获取类的类类型
            A a1 = new A();
            Class c = a1.getClass();
            /*
             * 2.获取方法 名称和参数列表来决定
             * getMethod获取的是public的方法
             * getDelcaredMethod自己声明的方法
             */
            try {
                //Method m =  c.getMethod("print", new Class[]{int.class,int.class});
                Method m = c.getMethod("print", int.class, int.class);

                //方法的反射操作
                //a1.print(10, 20);方法的反射操作是用m对象来进行方法调用 和a1.print调用的效果完全相同
                //方法如果没有返回值返回null,有返回值返回具体的返回值
                //Object o = m.invoke(a1,new Object[]{10,20});
                Object o = m.invoke(a1, 10, 20);
                System.out.println("==================");
                //获取方法print(String,String)
                Method m1 = c.getMethod("print", String.class, String.class);
                //用方法进行反射操作
                //a1.print("hello", "WORLD");
                o = m1.invoke(a1, "hello", "WORLD");
                System.out.println("===================");
                //  Method m2 = c.getMethod("print", new Class[]{});
                Method m2 = c.getMethod("print");
                // m2.invoke(a1, new Object[]{});
                m2.invoke(a1);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }

    public static class MethodDemo2 {
        public static void main(String[] args) {
            UserService us = new UserService();
            /*
             * 通过键盘输入命令执行操作
             * 输入update命令就调用update方法
             * 输入delete命令就调用delete方法
             * ...
             */
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                System.out.println("请输入命令:");
                String action = br.readLine();
                /*if("update".equals(action)){
                    us.update();
                }
                if("delete".equals(action)){
                    us.delete();
                }
                if("find".equals(action)){
                    us.find();
                }*/
                /*
                 * action就是方法名称， 都没有参数--->通过方法的反射操作就会简单很多
                 * 通过方法对象然后进行反射操作
                 */
                Class c = us.getClass();
                Method m = c.getMethod(action);
                m.invoke(us);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    public static class MethodDemo3 {

        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            User u1 = new User("zhangsan", "123456", 30);
            System.out.println(BeanUtil.getValueByPropertyName(u1, "username"));
            System.out.println(BeanUtil.getValueByPropertyName(u1, "userpass"));
        }

    }

    public static class MethodDemo4 {
        public static void main(String[] args) {
            ArrayList list = new ArrayList();

            ArrayList<String> list1 = new ArrayList<String>();
            list1.add("hello");
            //list1.add(20);错误的
            Class c1 = list.getClass();
            Class c2 = list1.getClass();
            System.out.println(c1 == c2);
            //反射的操作都是编译之后的操作

            /*
             * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的
             * Java中集合的泛型，是防止错误输入的，只在编译阶段有效，
             * 绕过编译就无效了
             * 验证：我们可以通过方法的反射来操作，绕过编译
             */
            try {
                Method m = c2.getMethod("add", Object.class);
                m.invoke(list1, 20);//绕过编译操作就绕过了泛型
                System.out.println(list1.size());
                System.out.println(list1);
                /*for (String string : list1) {
                    System.out.println(string);
                }*///现在不能这样遍历
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}
